// Database datapump definition
// Copyright 2006 (C) Ralph Thomas

#ifndef MISSION_DATAPUMPS_DATABASE_H
#define MISSION_DATAPUMPS_DATABASE_H

#include <boost/filesystem/path.hpp>
#include <adobe/value.hpp>
#include <adobe/dictionary.hpp>
#include <adobe/adam.hpp>

namespace datapumps {
	//
	/// The db_query datapump connects to the database specified with
	/// the "db:" parameter and returns the results from the "query:"
	/// parameter. Both "db:" and "query:" may be datapumps.
	///
	/// This factory function throws exceptions when the given parameters
	/// are invalid.
	///
	/// \param	path		scope the location of the db file to
	///				children of this path.
	/// \param	parameters	a dictionary containing the parameters.
	/// \param	sheet		the sheet to resolve @names into.
	/// \return	a db_query datapump.
	//
	adobe::value_t make_db_query_datapump( const boost::filesystem::path& path, const adobe::dictionary_t& parameters, adobe::sheet_t& sheet );
	//
	/// The db_row datapump connects to a row extracted by db_query and
	/// can extract a value. It can also update the value it extracts
	/// in the database when given an "update:" parameter. It is used
	/// (simply) like this:
	///
	///  dynamic_text( bind: db_row( row: @i, column: "name" ) );
	///
	/// to allow the datapump to update the value when it changes one
	/// must supply an "update:" parameter which is an UPDATE SQL
	/// query. The UPDATE query can use other values (accessed by
	/// column name) in the row by saying "@column_name;", for example:
	///
	/// generator( bind: db_query( query: "select id, name from t;" ), iterator: @i ) {
	///  dynamic_text( bind: db_row( row: @i, column: "name", update: "update t set name = @NEWVAL; where id = @id;;" ) );
	/// }
	///
	/// The "@NEWVAL;" string gets substituted with the new value.
	///
	/// \param	path		scope the location of the db file to
	///				children of this path.
	/// \param	parameters	a dictionary containing the parameters.
	/// \param	sheet		the sheet to resolve @names into.
	/// \return	a db_row datapump.
	//
	adobe::value_t make_db_row_datapump( const boost::filesystem::path& path, const adobe::dictionary_t& parameters, adobe::sheet_t& sheet );
	//
	/// The db_column datapump returns an individual column from a
	/// result set as returned by db_query.
	///
	/// \param	parameters	including "column" (string, column to get)
	///						and "result_set" (results from db_query).
	/// \param	sheet		the sheet to resolve @names into.
	/// \return	a db_column datapump.
	//
	adobe::value_t make_db_column_datapump( const adobe::dictionary_t& parameters, adobe::sheet_t& sheet );
	//
	/// The db_value datapump is a shortcut to get a single value out
	/// of the database (and to be able to update it). It should only
	/// be used for queries that will return a single value (and can
	/// be used for more complicated SQL queries, such as calculating
	/// an average, etc). It takes a "db:" parameter (the database to
	/// query, required), a "query:" parameter (the SQL query to run)
	/// and an "update:" parameter (the SQL query to update the db
	/// with, optional; only needed if you want to be able to update
	/// the value in the database).
	///
	/// It might be used like this:
	///
	///  dynamic_text( bind: db_value( db: "test.db", query: "select name from t where id = 0;" );
	///
	/// Or for a value that can be updated:
	///
	///  dynamic_text( bind: db_value( db: "test.db", query: "select name from t where id = 0;", update: "update t set name = @NEWVAL; where id = 0;" );
	///
	/// The "@NEWVAL;" string gets substituted with the new value in
	/// the update query.
	///
	/// \param	path		scope the location of the db file to
	///				children of this path.
	/// \param	parameters	a dictionary containing the parameters.
	/// \param	sheet		the sheet to resolve @names into.
	/// \return	the first result of the query.
	//
	adobe::value_t make_db_value_datapump( const boost::filesystem::path& path, const adobe::dictionary_t& parameters, adobe::sheet_t& sheet );
};

#endif

